# Tests/Functional/lit.cfg - Functional test suite lit config -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
from pkg_resources import parse_version
import os
import platform
import tempfile
import shlex
import sys
import lit
import re

# Set up lit config.
config.name = 'SwiftXCTestFunctionalTests'
config.os_info = (platform.system(), platform.mac_ver()[0])
config.test_format = lit.formats.ShTest(execute_external=False)
config.suffixes = ['.swift']

# Set up the substitutions used by the functional test suite.

# First, our tests need a way to compile source files into
# executables that are linked against swift-corelibs-xctest.
# We'll provide one via the %swiftc substitution.
#
# Linux tests are run after swift-corelibs-xctest is installed
# in the Swift library path, so we only need the path to `swiftc`
# in order to compile.
def _getenv(name):
    value = os.getenv(name, None)
    if value is None:
        lit_config.fatal(
            'Environment variable ${} is required to run tests on this '
            'platform, but it is not set.'.format(name))
    return value

built_products_dir = _getenv('BUILT_PRODUCTS_DIR')
# Force tests to build with -swift-version 5 for now.
swift_exec = [ _getenv('SWIFT_EXEC'), '-swift-version', '5', ]
swift_exec.extend(shlex.split(os.getenv('SWIFT_FLAGS', '')))
if not platform.system() == 'Windows':
    swift_exec.extend(['-Xlinker', '-rpath', '-Xlinker', built_products_dir,])
swift_exec.extend([
    '-L', built_products_dir,
    '-I', built_products_dir,
    '-I', os.path.join(built_products_dir, 'swift'),
    # A module cache in the built products directory is less likely to break in CI.
    '-module-cache-path', os.path.join(built_products_dir, 'XCTest.dir', 'ModuleCache'),
])

if platform.system() == 'Darwin':
    # On Darwin, we need to make sure swiftc references the
    # proper SDK, has a deployment target set, and more...
    # Here we rely on environment variables, produced by xcodebuild.
    sdk_root = _getenv('SDKROOT')
    platform_name = _getenv('PLATFORM_NAME')
    deployment_target = _getenv('MACOSX_DEPLOYMENT_TARGET')

    target = '{}-apple-{}{}'.format(
        platform.machine(), platform_name, deployment_target)
    swift_exec.extend([
        '-sdk', sdk_root,
        '-target', target,
        '-F', built_products_dir,
        # FIXME: We must include the C header dependencies of any module we wish
        #        to use, due to a limitation in the Swift compiler. See SR-655
        #        for details. Here, we include the headers from CoreFoundation.
        '-I', os.path.join(built_products_dir, 'usr', 'local', 'include'),
    ])
else:
    # We need to jump through extra hoops to link swift-corelibs-foundation.
    foundation_dir = _getenv('FOUNDATION_BUILT_PRODUCTS_DIR')
    if platform.system() == 'Windows':
        sdkroot = os.getenv('SDKROOT', None)
        if sdkroot:
            swift_exec.extend(['-sdk', sdkroot])
        swift_exec.extend(['-Xlinker', '-nodefaultlib:libcmt'])
    else:
        swift_exec.extend([
          '-Xlinker', '-rpath', '-Xlinker', foundation_dir,
          '-Xlinker', '-rpath', '-Xlinker', os.path.join(foundation_dir, 'Foundation'),
          '-Xlinker', '-rpath', '-Xlinker', os.path.join(foundation_dir, 'Sources', 'Foundation'),
          '-Xlinker', '-rpath', '-Xlinker', os.path.join(foundation_dir, 'Sources', 'FoundationNetworking'),
          '-Xlinker', '-rpath', '-Xlinker', os.path.join(foundation_dir, 'Sources', 'FoundationXML'),
          '-Xlinker', '-rpath', '-Xlinker', os.path.join(foundation_dir, 'lib'),
        ])
    swift_exec.extend([
        '-L', foundation_dir,
        '-L', os.path.join(foundation_dir, 'Foundation'),
        '-L', os.path.join(foundation_dir, 'Sources', 'Foundation'),
        '-L', os.path.join(foundation_dir, 'Sources', 'FoundationNetworking'),
        '-L', os.path.join(foundation_dir, 'Sources', 'FoundationXML'),
        '-L', os.path.join(foundation_dir, 'lib'),
        '-I', foundation_dir,
        '-I', os.path.join(foundation_dir, 'swift'),
        '-I', os.path.join(foundation_dir, '_CModulesForClients'),
        '-Xcc', '-F', '-Xcc', foundation_dir,
    ])

    # We also need to link swift-corelibs-libdispatch, if
    # swift-corelibs-foundation is using it.
    libdispatch_src_dir = os.getenv('LIBDISPATCH_SRC_DIR')
    libdispatch_build_dir = os.getenv('LIBDISPATCH_BUILD_DIR')
    libdispatch_overlay_dir = os.getenv('LIBDISPATCH_OVERLAY_DIR')
    if ((libdispatch_src_dir is not None) 
        and (libdispatch_build_dir is not None)
        and (libdispatch_overlay_dir is not None)):
            swift_exec.extend([
                '-Xcc', '-fblocks',
                '-I', libdispatch_src_dir,
                '-I', libdispatch_overlay_dir,
                '-I', os.path.join(libdispatch_overlay_dir, 'swift'),
                '-L', libdispatch_build_dir,
                '-L', os.path.join(libdispatch_build_dir, 'src'),
                '-L', os.path.join(libdispatch_build_dir, 'src', 'BlocksRuntime'),
                '-L', os.path.join(libdispatch_build_dir, 'src', 'swift'),
                '-vfsoverlay', os.path.join(libdispatch_build_dir, 'dispatch-vfs-overlay.yaml'),
            ])

            if platform.system() != 'Windows':
                swift_exec.extend([
                    '-Xlinker', '-rpath', '-Xlinker', libdispatch_build_dir,
                ])

# Having prepared the swiftc command, we set the substitution.
config.substitutions.append(('%{swiftc}', ' '.join(swift_exec)))

# Add the %{xctest_checker} substitution, which is a Python script that
# can be used to compare the actual XCTest output to the expected
# output.
xctest_checker = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    'xctest_checker',
    'xctest_checker.py')
config.substitutions.append(('%{xctest_checker}', '%%{python} %s' % xctest_checker))

# Add Python to run xctest_checker.py tests as part of XCTest tests
config.substitutions.append( ('%{python}', shlex.quote(sys.executable)) )

# Conditionally report the Swift 5.5 Concurrency runtime as available depending on the OS and version.
# Darwin is the only platform where this is a limitation.
(run_os, run_vers) = config.os_info
if run_os == 'Darwin':
    assert run_vers != "", "No runtime version set."
    if parse_version(run_vers) >= parse_version('12.0'):
        config.available_features.add('concurrency_runtime')
else:
    # Non-Darwin platforms have a concurrency runtime
    config.available_features.add('concurrency_runtime')
if run_os == 'Windows':
    config.available_features.add('OS=windows')
